//
//  Export.swift
//  JKTool
//
//  Created by 姜奎 on 2022/7/19.
//

import Foundation

extension JKTool {
    struct Export: ParsableCommand {
        static var configuration = CommandConfiguration(
            commandName: "export",
            _superCommandName: "jktool",
            abstract: "export命令对于固定工程格式封装",
            version: "1.0.0"
        )
        
        @Option(name: .shortAndLong, help: "导出环境，default：Release")
        var configuration: String = "Release"
        
        @Option(name: .shortAndLong, help: "Scheme")
        var scheme: String
        
        @Option(name: .long, help: "内容格式请参照：JKTool config")
        var configPath: String
        
        @Option(name: .shortAndLong, help: "执行路径")
        var path: String?

        mutating func run() {
            
            guard let project = Project.project(directoryPath: path ?? FileManager.default.currentDirectoryPath) else {
                return po(tip: "\(path ?? FileManager.default.currentDirectoryPath)目录没有检索到工程", type: .error)
            }
            
            guard project.rootProject == project else {
                return po(tip: "请在项目根目录执行脚本", type: .error)
            }
            
            let configP = configPath.convertRelativePath(absolutPath: project.directoryPath)
            
            guard let data = try? Data(contentsOf: URL(fileURLWithPath:configP)) else {
                return po(tip: "请检查配置文件是否存在！(\(configP))",type: .error)
            }
            
            guard let configs = try? JSONDecoder().decode(ProjectConfigModel.self, from: data) else {
                return po(tip: "请检查配置文件格式是否正确！(\(configP))",type: .error)
            }
            
            let date = Date.init().timeIntervalSince1970
            let archivePath =  configs.needConfigurationInProductsPath == true ? "\(project.buildPath)/\(configuration)/\(scheme).xcarchive": "\(project.buildPath)/\(scheme).xcarchive"
            
            let exportPath = configs.needConfigurationInProductsPath == true ? "\(project.buildPath)/\(configuration)": project.buildPath
            
            guard FileManager.default.fileExists(atPath: archivePath) else {
                return po(tip: "【\(scheme)】没有找到可导出文件(\(archivePath))",type: .error)
            }
            
            po(tip: "======Export IPA 开始======")
            
            guard let exportConfig = configs.exportConfigList.first(where: { $0.configuration == configuration }) else {
                return po(tip: "【\(scheme)】exportConfigList没有匹配到\(configuration)",type: .error)
            }
            
            var savePath: String?
            if let path = exportConfig.saveConfig?.path {
                savePath = path.convertRelativePath(absolutPath: project.directoryPath)
            }
            
            let shell = ShellOutCommand.export(scheme: scheme, archivePath: archivePath, export: exportConfig.exportOptionsPath.convertRelativePath(absolutPath:configP), exportPath: exportPath, fileExtension: Platform(configs.sdk).fileExtension(), toSavePath: savePath, allFiles: exportConfig.saveConfig?.allFiles)
            do {
                let exportResult = try shellOut(to: shell, at: project.directoryPath)
                _ = project.writeExportLog(log: "export command:\n[\(shell.string)]\n" + exportResult, scheme: scheme, configuration: configuration)
            } catch  {
                let error = error as! ShellOutError
                let path = project.writeExportLog(log: "export command:\n[\(shell.string)]\n" + error.message + error.output, scheme: scheme, configuration: configuration)
                po(tip: "【\(scheme)】 Export失败，详情(\(path))",type: .error)
            }
            
            po(tip: "======Export IPA 完成[\(GlobalConstants.duration(to: date) + " s")]======")
        }
    }
}
